#include "frmudpclient.h"
#include "ui_frmudpclient.h"
#include "src/interface/api/qthelper.h"
#include "src/interface/api/qthelperdata.h"
#include <QPalette>
#include "src/player/images/UDPRecieve.h"
#include "src/control/keybordcontrol/keywidget.h"
#include "src/control/keybordcontrol/KeyBoardManger.h"
#include "src/common/log/log.h"
#include "../../player/images/ImageReceiver.h"
#include <QMessageBox>
#include <QPushButton>
frmUdpClient::frmUdpClient(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::frmUdpClient),m_isPressed(false)
{
    ui->setupUi(this);
    //设置imageLabel的背景色
    QPalette palette = ui->imageLabel->palette();
    palette.setColor(ui->imageLabel->backgroundRole(), Qt::black);
    ui->imageLabel->setAutoFillBackground(true);
    ui->imageLabel->setPalette(palette);
    ui->imageLabel->setGeometry(6, 6 , 612,430);
  //  ui->imageLabel->resize(650, 510);
    ui->txtMain->setGeometry(6,450, 612,202);
    m_pReceiver = CImageReceiver::GetInStance();
    ui->takeoverBtn->setFixedSize(80, 80);
    ui->takeoverBtn->setMask(QRegion(0,0,ui->takeoverBtn->width(), ui->takeoverBtn->height(),QRegion::Ellipse));
    ui->takeoverBtn->setStyleSheet("QPushButton { background-color: darkgray; }"
                                               "QPushButton:hover { background-color: gray; }"
                                               "QPushButton:pressed { background-color: black; }");
    setMouseTracking(true);
    ui->subBtn->setFixedSize(64,37);
    ui->subBtn->setStyleSheet("QPushButton {"
                               "    border-radius: 24px;" // 设置圆角半径
                               "    background-image: url(:/btn/resource/button/cancelSub.png);" // 设置背景图片
                               "    background-repeat: no-repeat;"
                               "    background-position: center;"
                               "}");

    connect(ui->subBtn,&QPushButton::clicked, this, [=](){
        onSelectSubClicked();
    },Qt::QueuedConnection);

    m_pMqqtClient = new CMqttClient(this);
    m_pMqqtClient->init();
    connect(m_pMqqtClient, &CMqttClient::SendBasicDatas, this, &frmUdpClient::onRecieveBasicDatas);

    //对接管的消息进行显示
    connect(m_pMqqtClient, &CMqttClient::SendTakeOverInfo, this, &frmUdpClient::onDisplayTakeOverInfo);
    //连接鼠标进入和离开事件
    installEventFilter(this);
    this->initForm();
    this->initConfig();


}

frmUdpClient::~frmUdpClient()
{
    if(m_pMqqtClient!= nullptr){
        delete m_pMqqtClient;
        m_pMqqtClient = nullptr;
    }
    delete ui;
}
bool frmUdpClient::eventFilter(QObject *watched, QEvent *event)
{
    //双击清空
    if (event->type() == QEvent::Enter){
        if(m_isPressed){

            ui->subBtn->setText("取消");
        }else{
            ui->subBtn->setText("订阅");
        }
    }
    if(event->type() == QEvent::Leave){
        ui->subBtn->setText("");
    }
    return QWidget::eventFilter(watched, event);
}

void frmUdpClient::initForm()
{
    QFont font;
    font.setPixelSize(16);
    ui->txtMain->setFont(font);
    ui->txtMain->viewport()->installEventFilter(this);

    //实例化对象并绑定信号槽
    socket = new QUdpSocket(this);
    connect(socket, SIGNAL(readyRead()), this, SLOT(readData()));
#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
    connect(socket, SIGNAL(errorOccurred(QAbstractSocket::SocketError)), this, SLOT(error()));
#else
    connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error()));
#endif

    //定时器发送数据
    timer = new QTimer(this);

    //填充数据到下拉框
   // ui->cboxInterval->addItems(AppData::Intervals);
   // ui->cboxData->addItems(AppData::Datas);
    ui->cboxDogSn->addItems(AppData::DogSn);

    //创建QCombox
    ui->cboxDogSn->setEditable(true);
    //选择信号槽，当选项改变时就触发
    QObject::connect(ui->cboxDogSn, QOverload<int>::of(&QComboBox::currentIndexChanged), [&](int index){
        if (index == 0){
            return;
        }
        //获取当前的文本
        QString selectedSn = ui->cboxDogSn->currentText();
        ui->cboxDogSn->blockSignals(true);
        //设置下拉框获取当前显示文本为第一个选择SN号
        ui->cboxDogSn->setCurrentText(selectedSn);
        ui->cboxDogSn->blockSignals(false);
    });
    //定义字符串列表
    AppData::loadIP(ui->cboxBindIP);
}
//初始化配置
void frmUdpClient::initConfig()
{
    ui->ckHexSend->setChecked(AppConfig::HexSendUdpClient);
    connect(ui->ckHexSend, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));

    ui->ckHexReceive->setChecked(AppConfig::HexReceiveUdpClient);
    connect(ui->ckHexReceive, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));

    ui->ckAscii->setChecked(AppConfig::AsciiUdpClient);
    connect(ui->ckAscii, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));

    ui->ckDebug->setChecked(AppConfig::DebugUdpClient);
    connect(ui->ckDebug, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));

    ui->cboxBindIP->setCurrentIndex(ui->cboxBindIP->findText(AppConfig::UdpBindIP));
    connect(ui->cboxBindIP, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));
    connect(m_pReceiver.get(), &CImageReceiver::SendDisplaySignal,this, &frmUdpClient::onDisplayImage);
    this->initTimer();
}

void frmUdpClient::saveConfig()
{
    AppConfig::HexSendUdpClient = ui->ckHexSend->isChecked();
    AppConfig::HexReceiveUdpClient = ui->ckHexReceive->isChecked();
    AppConfig::AsciiUdpClient = ui->ckAscii->isChecked();
    AppConfig::DebugUdpClient = ui->ckDebug->isChecked();
    //AppConfig::AutoSendUdpClient = ui->ckAutoSend->isChecked();
   // AppConfig::IntervalUdpClient = ui->cboxInterval->currentText().toInt();
    AppConfig::UdpBindIP = ui->cboxBindIP->currentText();
    AppConfig::writeConfig();

    this->initTimer();
}

void frmUdpClient::initTimer()
{
    if (timer->interval() != AppConfig::IntervalUdpClient) {
        timer->setInterval(AppConfig::IntervalUdpClient);
    }

    if (AppConfig::AutoSendUdpClient) {
        if (!timer->isActive()) {
            timer->start();
        }
    } else {
        if (timer->isActive()) {
            timer->stop();
        }
    }
}

void frmUdpClient::append(int type, const QString &data, bool clear)
{
    static int currentCount = 0;
    static int maxCount = 100;
    QtHelper::appendMsg(ui->txtMain, type, data, maxCount, currentCount, clear, ui->ckShow->isChecked());
}

void frmUdpClient::error()
{
    append(3, socket->errorString());
}

void frmUdpClient::readData()
{
    QHostAddress host;
    quint16 port;
    QByteArray data;
    QString buffer;

    while (socket->hasPendingDatagrams()) {
        data.resize(socket->pendingDatagramSize());
        socket->readDatagram(data.data(), data.size(), &host, &port);

        if (AppConfig::HexReceiveUdpClient) {
            buffer = QtHelperData::byteArrayToHexStr(data);
        } else if (AppConfig::AsciiUdpClient) {
            buffer = QtHelperData::byteArrayToAsciiStr(data);
        } else {
            buffer = QString(data);
        }

        QString ip = host.toString();
        ip = ip.replace("::ffff:", "");
        if (ip.isEmpty()) {
            continue;
        }

        QString str = QString("[%1:%2] %3").arg(ip).arg(port).arg(buffer);
        append(1, str);

        if (AppConfig::DebugUdpClient) {
            int count = AppData::Keys.count();
            for (int i = 0; i < count; i++) {
                if (AppData::Keys.at(i) == buffer) {
                    sendData(ip, port, AppData::Values.at(i));
                    break;
                }
            }
        }
    }
}

void frmUdpClient::sendData(const QString &ip, int port, const QString &data)
{
    QList<double> doubleValues;

    QByteArray buffer;
    QByteArray Data;
    if (AppConfig::HexSendUdpClient) {
        buffer = QtHelperData::hexStrToByteArray(data);
    } else if (AppConfig::AsciiUdpClient) {
        buffer = QtHelperData::asciiStrToByteArray(data);
    } else {
         buffer = data.toUtf8();
        //将字符串转换为double类型数据
    }
    //绑定网卡和端口,没有绑定过才需要绑定
    //采用端口是否一样来判断是为了方便可以直接动态绑定切换端口
    if (socket->localPort() != AppConfig::UdpBindPort) {
        socket->abort();
        socket->bind(QHostAddress(AppConfig::UdpBindIP), AppConfig::UdpBindPort);
    }
    //指定地址和端口发送数据
    socket->writeDatagram(buffer, QHostAddress(ip), port);

    QString str = QString("[%1:%2] %3").arg(ip).arg(port).arg(data);
    append(0, str);
}


//图片显示
void  frmUdpClient::onDisplayImage(const cv::Mat &image)
{
    QImage qImage(image.data, image.cols, image.rows, static_cast<int>(image.step), QImage::Format_BGR888);
    QPixmap pixmap = QPixmap::fromImage(qImage);
    // Display the image in the QLabel
    ui->imageLabel->setPixmap(pixmap);
    // Resize the label to fit the image
    ui->imageLabel->resize(pixmap.size());
    // Update the UI
    QCoreApplication::processEvents();
}

void frmUdpClient::onRecieveBasicDatas(const QString &msg){
    Json::Value rootcfg = Json::Value::null;
    Json::Reader reader;
    bool isCucessful = reader.parse(msg.toStdString(), rootcfg);
    if(!isCucessful){
        return;
    }else{
        QString robotIp = QString::fromStdString(rootcfg["robotIp"].asString());
        double robotPower = rootcfg["robotPower"].asDouble();
        QString robotSn = QString::fromStdString(rootcfg["robotSn"].asString());
        //将robotSn插入到combox中
        //查找键是否存在
        auto iter = m_baseMap.find(robotSn);
        if(iter!= m_baseMap.end()){
            if(iter->second!=robotIp){
                iter->second = robotIp;
            }
        }else{
            m_baseMap.insert(std::make_pair(robotSn, robotIp));
            ui->cboxDogSn->addItem(robotSn);
        }
        //将获取的消息添加转成文字添加到txtMain中
        QString  msg = "robotSn: " + robotSn  + " robotPower: " + QString::number(robotPower);
        append(0, msg);
    }
}

void frmUdpClient::setTopic(const QString &sigCmdTopic, const QString &picRecTopic)
{
    LOG_INFO("sigCmdTopic: " << sigCmdTopic.toStdString() <<"   picRecTopic: " << picRecTopic.toStdString());
}

void frmUdpClient::onDisplayTakeOverInfo(const QString & msg){
    //1.消息进行解析
    Json::Value rootcfg = Json::Value::null;
    Json::Reader reader;
    bool isCucessful = reader.parse(msg.toStdString(), rootcfg);
    if(!isCucessful){
        return;
    }else{
        QString robotSn = QString::fromStdString(rootcfg["robotSn"].asString());
        int  level = rootcfg["takeOverLevel"].asInt();
        if(level == E_PlatFormTakeOver){  //请求平台接管
            QString msg = "Please Take Over " + robotSn + "?";
            if(QMessageBox::Yes == QMessageBox::question(this, "TakeOver", msg)){
                LOG_INFO("Take Over Successful!");
                ui->takeoverBtn->setStyleSheet("QPushButton { background-color: green; }"
                                               "QPushButton:hover { background-color: limegreen; }"
                                               "QPushButton:pressed { background-color: darkgreen; }");
                ui->ckTakeOverStatus->setChecked(true);
                ui->ckTakeOverStatus->setText("平台接管");
                ui->ckTakeOverStatus->setEnabled(false);
            }else{
                LOG_INFO("Take Over Failed!");
            }
        }
        if(level  == E_LargeModelTakeOver){
            LOG_INFO("RobotSn is TokenOver by LargerModel, RobotSn is " << robotSn.toStdString());
            ui->takeoverBtn->setStyleSheet("QPushButton { background-color: red; }"
                                           "QPushButton:hover { background-color: darkred; }"
                                           "QPushButton:pressed { background-color: firebrick; }");
            ui->ckTakeOverStatus->setChecked(true);
            ui->ckTakeOverStatus->setText("大模型接管");
            ui->ckTakeOverStatus->setEnabled(false);
        } else{
//            ui->takeoverBtn->setStyleSheet("QPushButton { background-color: darkgray; }"

//                                           "QPushButton:hover { background-color: gray; }"
//                                           "QPushButton:pressed { background-color: black; }");
//            ui->ckTakeOverStatus->setChecked(true);
//            ui->ckTakeOverStatus->setText("暂未接管");
//            ui->ckTakeOverStatus->setEnabled(true);
        }
    }
}

void frmUdpClient::onSelectSubClicked(){

    if(!m_isPressed){
        m_isPressed = true;
        ui->subBtn->setStyleSheet("QPushButton {"
                                  "    border-radius: 24px;" // 设置圆角半径
                                  "    background-color: transparent;" // 设置背景透明
                                  "    background-image: url(:/btn/resource/button/subscribe.png);" // 设置背景图片
                                  "    background-repeat: no-repeat;"
                                  "    background-position: center;"
                                  "}");
        subTopic(); //订阅

    } else{
        m_isPressed = false;
        ui->subBtn->setStyleSheet("QPushButton {"
                                  "    border-radius: 24px;" // 设置圆角半径
                                  "    background-color: transparent;" // 设置背景透明
                                  "    background-image: url(:/btn/resource/button/cancelSub.png);" // 设置背景图片
                                  "    background-repeat: no-repeat;"
                                  "    background-position: center;"
                                  "}");
        cancelSubTopic();
    }
}




/*订阅*/
void frmUdpClient::subTopic(){
    QString data = ui->txtMain->toPlainText();
    //获取IP和对应端口的数据
    //1.获取当前选中的文本
    QString dogSnText = ui->cboxDogSn->currentText();
    if(!dogSnText.isEmpty()){
        QString dogIp, imgTopic, imageDataTopic;
        //查找当前条目对应的IP
        auto iter = m_baseMap.find(dogSnText);
        if(iter!=m_baseMap.end()){
            dogIp= iter->second;
        }
        imgTopic = "Images" + iter->first;
        imageDataTopic = "ImagesData" +  iter->first;
        //设置
        m_pMqqtClient->SetCmdTopic(iter->first); //订阅信令
        m_pMqqtClient->SendImgRequset( imgTopic,"xhjqr");  //发送图片消息
        m_pMqqtClient->SendImagesDataTopic(imageDataTopic, true);
    }
    AppData::saveData(data);
}
/*取消定订阅*/
void frmUdpClient::cancelSubTopic(){
    QString dogSnText = ui->cboxDogSn->currentText();
    if(!dogSnText.isEmpty()){
        QString imgTopic, imageDataTopic;
        //查找当前条目对应的IP
        auto iter = m_baseMap.find(dogSnText);
        if(iter!=m_baseMap.end()){
            imgTopic = "Images" + iter->first;
            imageDataTopic = "ImagesData" +  iter->first;
            //设置
            m_pMqqtClient->SendImgRequset( imgTopic,"cancel");  //发送图片消息
            m_pMqqtClient->SendImagesDataTopic(imageDataTopic, false);
        }
    }
    append(0, "", true);
}